// DwarfMgr.cs using System.Data; using System.Data.SqlClient; using System.Runtime.CompilerServices; using System.EnterpriseServices; using System.Reflection; using Database; using Dwarf; //Registration details. //COM+ application name as it appears in the COM+ catalog. [assembly: ApplicationName("DwarfMgr")] [assembly: ApplicationActivation(ActivationOption.Library)] //Strong name for assembly. [assembly: AssemblyKeyFileAttribute("components/DwarfMgr.snk")] [assembly: AssemblyVersion("1.0.0.0")] namespace DwarfMgr { [Transaction(TransactionOption.Required)] public class DwarfMgr : ServicedComponent { // yes, marriage could be a method on Dwarf, // and could be done easier with a smaller update // but we are trying to demonstrate transaction composition [AutoComplete] public void Marry(int groom_id, int bride_id){ Dwarf.Dwarf dw = new Dwarf.Dwarf(); if(groom_id == bride_id){ throw new System.Exception("You can't marry yourself!"); } // is this a "select for update / select holdlock", or do we have a race condition??? DataSet gds = dw.Get(groom_id); DataSet bds = dw.Get(bride_id); if(gds.Tables[0].Rows[0]["spouse_id"] != System.DBNull.Value){ throw new System.Exception("Groom already married!"); } if(bds.Tables[0].Rows[0]["spouse_id"] != System.DBNull.Value){ throw new System.Exception("Bride already married!"); } int gHome; int bHome; if(gds.Tables[0].Rows[0]["home_id"] == System.DBNull.Value){ gHome = 0; }else{ gHome = System.Int32.Parse(gds.Tables[0].Rows[0]["home_id"].ToString()); } if(bds.Tables[0].Rows[0]["home_id"] == System.DBNull.Value){ bHome = 0; }else{ bHome = System.Int32.Parse(bds.Tables[0].Rows[0]["home_id"].ToString()); } dw.Update(groom_id, gds.Tables[0].Rows[0]["dwarf_name"].ToString(), System.Int32.Parse(gds.Tables[0].Rows[0]["born"].ToString()), gHome, bride_id); // uncomment next two lines to verify ACID transaction // int zero = 0; // int divide_by = 5 / zero; dw.Update(bride_id, bds.Tables[0].Rows[0]["dwarf_name"].ToString(), System.Int32.Parse(bds.Tables[0].Rows[0]["born"].ToString()), gHome, groom_id); } } }